package services

import (
	"crypto/md5"
	"fmt"
	"net/http"
	"strings"

	"bsm/constants"
	"bsm/daos"
	"bsm/logger"
	"bsm/models"

	"github.com/gin-gonic/gin"
)

// 在services包中定义接口
type AuthService interface {
	UserLogin(username, password string) (bool, int, models.UserWithRoles)
	GetWebUser(user models.ProjectUser) (models.WebUser, error)
	JWTAuthUser(ctx *gin.Context) bool
	Logout(c *gin.Context)
	CheckUserRole(userID string, roleID string) (bool, error)
}

// 实现类改名为authServiceImpl
type authServiceImpl struct {
	userDao daos.UserDao
}

func NewAuthService(userDao daos.UserDao) AuthService {
	return &authServiceImpl{
		userDao: userDao,
	}
}

func (as *authServiceImpl) UserLogin(username, password string) (bool, int, models.UserWithRoles) {
	hash := md5.Sum([]byte(username + "-" + password))
	hashStr := fmt.Sprintf("%x", hash)

	status, user := as.userDao.GetUserByCredentials(username, hashStr)

	if status != constants.LoginSuccess || user == nil {
		return false, status, models.UserWithRoles{}
	}

	logger.WithFields(map[string]interface{}{
		"layer":     "services",
		"operation": "AuthServiceImpl-UserLogin",
		"user_id":   user.UserID,
		"user_name": user.UserName,
		"org_code":  user.OrgCode,
	}).Info("用户登录成功")

	userWithRoles, err := as.userDao.GetUserWithRoles(user.UserID)
	if err != nil {
		logger.WithFields(map[string]interface{}{
			"layer":     "services",
			"operation": "AuthServiceImpl-UserLogin",
			"user_id":   user.UserID,
			"user_name": user.UserName,
			"org_code":  user.OrgCode,
			"error":     err.Error(),
		}).Error("获取用户角色失败")
		return false, status, models.UserWithRoles{}
	}

	if !user.IsActive {
		return false, constants.LoginUserDisabled, models.UserWithRoles{}
	}
	return true, status, *userWithRoles
}

func (as *authServiceImpl) GetWebUser(user models.ProjectUser) (models.WebUser, error) {
	org, err := as.userDao.GetOrgByCode(user.OrgCode)
	if err != nil {
		logger.WithFields(map[string]interface{}{
			"layer":     "services",
			"operation": "AuthServiceImpl-UserLogin",
			"org_code":  user.OrgCode,
			"error":     err.Error(),
		}).Error("获取用户所属机构失败")
		return models.WebUser{}, err
	}

	hasAdminRole, _ := as.userDao.CheckUserRole(user.UserID, models.UserRole_Admin)

	var webUser models.WebUser
	webUser.ID = user.ID
	webUser.UserID = user.UserID
	webUser.UserName = user.UserName
	if hasAdminRole {
		webUser.UserType = 1
	} else {
		webUser.UserType = 0
	}
	webUser.OrgCode = user.OrgCode
	webUser.OrgLevel = org.OrgLevel
	webUser.OrgName = org.OrgName
	webUser.OrgPrefix = org.Prefix
	webUser.OrgFullName = org.FullName
	webUser.OrgLiteName = org.LiteName

	return webUser, nil
}

func (as *authServiceImpl) JWTAuthUser(ctx *gin.Context) bool {

	// 获取用户账号
	userID, exists := ctx.Get("user_id")
	if !exists {
		ctx.JSON(http.StatusUnauthorized, models.ResponseModel{
			Code: 1,
			Msg:  "用户信息获取失败",
		})
		return false
	}

	// 获取用户类型
	orgCode, exists := ctx.Get("org_code")
	if !exists {
		ctx.JSON(http.StatusUnauthorized, models.ResponseModel{
			Code: 1,
			Msg:  "用户组织代码获取失败",
		})
		return false
	}

	// 类型断言
	userIDStr, ok := userID.(string)
	if !ok {
		// ctx.JSON(http.StatusUnauthorized, gin.H{"信息": "用户账号类型无效"})
		ctx.JSON(http.StatusUnauthorized, models.ResponseModel{
			Code: 1,
			Msg:  "用户账号类型无效",
		})
		return false
	}

	orgCodeStr, ok := orgCode.(string)
	if !ok {
		// ctx.JSON(http.StatusUnauthorized, gin.H{"信息": "用户组织代码无效"})
		ctx.JSON(http.StatusUnauthorized, models.ResponseModel{
			Code: 1,
			Msg:  "用户组织代码无效",
		})
		return false
	}

	logger.WithFields(map[string]interface{}{
		"layer":     "services",
		"operation": "AuthServiceImpl-JWTAuthUser",
		"user_id":   userIDStr,
		"org_code":  orgCodeStr,
	}).Info("JWT用户认证成功")

	return true

}

// LogoutHandler 处理用户登出
func (as *authServiceImpl) Logout(c *gin.Context) {
	// 1. 从请求头或cookie获取token
	tokenString := c.GetHeader("Authorization")
	if tokenString != "" {
		tokenString = strings.TrimPrefix(tokenString, "Bearer ")
	} else {
		// 从cookie获取
		tokenString, _ = c.Cookie("jwt_token")
	}

	if tokenString != "" && len(tokenString) >= 10 {
		logger.WithFields(map[string]interface{}{
			"layer":        "services",
			"operation":    "AuthServiceImpl-Logout",
			"token_prefix": tokenString[:10],
		}).Info("用户登出")
	} else {
		logger.WithFields(map[string]interface{}{
			"layer":     "services",
			"operation": "AuthServiceImpl-Logout",
		}).Info("用户登出（无有效token）")
	}

	// 2. 清除客户端cookie
	c.SetCookie("jwt_token", "", -1, "/", "", false, true)

	// 3. 返回成功响应
	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "Successfully logged out",
	})
}

func (as *authServiceImpl) CheckUserRole(userID string, roleID string) (bool, error) {
	return as.userDao.CheckUserRole(userID, roleID)
}
